/* $RCSFile: AddEditImagePage.cs $
 * Apache license v2 2011 by Christian Surieux
 * $Source: ?/AddonNice.ImageSettings/UI/AddEditImagePage.cs $
 * $log$
 * Revision 7 2010/08/09 09:44:02  christian.surieux
 *   Added Log to cs sources files
 */

using System;
using System.IO;
using System.Text;
using System.Drawing;
using System.Drawing.Imaging;
using System.Xml;
using System.Configuration;
using System.Collections;
using System.Reflection;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Globalization;

using AddonNice.UI;
using AddonNice.UI.WebControls;
using AddonNice.Helpers;
using AddonNice.Security;
using AddonNice.Configuration;
using AddonNice.Diagnostics;
using AddonNice.Core;

using AddonNice.CRMImage;
using AddonNice.Settings.CRMImage;

using Trace2    =   System.Diagnostics.Trace;
using Image2    =   System.Drawing.Image;

namespace AddonNice.CRMImage.UI
{
    /// <summary>
    /// AddEditImagePage inherits from AddEditItemPage <br/>
	/// </summary>
    public class AddEditImagePage : AddEditItemPage
    {
        protected CRMImageDB ImageDB    =   new CRMImageDB();

		#region license

        private CRMImageManager _ImM;
        
        /// <summary>
        /// Check for ImageManager and AddonNice license
        /// </summary>
        protected override bool CheckLicense
        {
            get
            {
                if (_ImM == null)
                    _ImM = new CRMImageManager();
                if (_ImM != null)
                    return ( _ImM.License.IsValid && base.CheckLicense ) ;
                return false;
            }
        }

        /// Check for ImageManager AddonNice license demo mode
        public override bool IsDemo
        {
            get
            {
                if (_ImM == null)
                    _ImM = new CRMImageManager();
                if (_ImM != null)
                    return ( _ImM.DemoMode && base.IsDemo );
                return true;
            }
        }
        
        #endregion license

        int _ImageDBID = 0;
        public int ImageDBID
        {
            get
            {
                if (_ImageDBID == 0)
                {
                    // Determine ItemID if specified
                    if (!IsDesignMode)
                    {
                        string str = Request.Params[ImStr.ImageDBID];
                        if (!string.IsNullOrEmpty(str))
                        {
                            try
                            {
                                _ImageDBID = Int32.Parse(str);
                            }
                            catch (Exception ex)
                            {
                                if ( CrmImageTrace.Sw.TraceError )
                                    Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[E]AddEditImagePage _ImageDBID Parse failed for ImageDBID : '{0}', ex : {1}", str, ex),CrmImageTrace.Sw.Info);
                                throw;
                            }
                        }
                    }
                }
                return _ImageDBID;
            }
            set
            {
                _ImageDBID = value;
            }

        }

        //Where are we going to save the CRMImage?
        string _PathToSave = string.Empty;
        public string PathToSave
        {
            get
            {
                if (string.IsNullOrEmpty(_PathToSave))
                {
                    _PathToSave     = Server.MapPath(AlbumPath) + "\\";
                    //Make sure the CRMImage target directory exists
                    if (!System.IO.Directory.Exists(_PathToSave))
                    {
                        try
                        {
                            System.IO.Directory.CreateDirectory(_PathToSave);
                        }
                        catch (Exception ex)
                        {
                            if ( CrmImageTrace.Sw.TraceError )
                                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[E]AddEditImagePage PathStoSave : {0}, ex :{1}", _PathToSave, ex),CrmImageTrace.Sw.Info);
                            throw;
                        }
                    }
                }
                return _PathToSave;
            }
        }

        
        /// <summary>
        /// Where are we going to read the CRMImage?
        /// </summary>
        string _AlbumPath = string.Empty;
        public string AlbumPath
        {
            get
            {
                if (string.IsNullOrEmpty(_AlbumPath))
                {
                    if ( moduleSettingsDic[ImStr.CustomAlbumPath].ToBool() )
					        _AlbumPath  =   moduleSettingsDic[ImStr.AlbumPath].FullPath;
                    else    _AlbumPath  =   portalSettings.CustomSettings[ImStr.AlbumPath].FullPath;
                    if ( CrmImageTrace.Sw.TraceVerbose )
                        Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]AddEditImagePage GET AlbumPath: {0}", _AlbumPath),CrmImageTrace.Sw.Info);
                }
                return _AlbumPath;
            }
        }

        /// <summary>
        /// Current Library
        /// </summary>
        int _ImageLibId = int.MinValue;
        public int ImageLibId
        {
            get
            {
                if (_ImageLibId == int.MinValue)
                {
					_ImageLibId  =   moduleSettingsDic[ImStr.ImageLibId].ToInt();
                    if ( CrmImageTrace.Sw.TraceVerbose )
                        Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]AddEditImagePage GET ImageLibId: {0}", _ImageLibId),CrmImageTrace.Sw.Info);
                }
                return _ImageLibId;
            }
        }

        public string ThumbnailFilename
        {
            get { return (string)ViewState[ImStr.ThumbnailFilename]; }
            set { ViewState[ImStr.ThumbnailFilename] = value; }
        }

        public string ModifiedFilename
        {
            get { return (string)ViewState[ImStr.ModifiedFilename]; }
            set { ViewState[ImStr.ModifiedFilename] = value; }
        }

        protected override string UrlReferrer
        {
            get
            {
                StringBuilder sb    =   new StringBuilder();
                bool hasParent      =   false;
                if ( (Request.QueryString[ImStr.ParentPageNum] != null ) && (Request.QueryString[ImStr.ItemCrmID] != null ) )
                {
                    sb.AppendFormat("{0}={1}", ImStr.ParentPageNum, Request.QueryString[ImStr.ParentPageNum]);
                    sb.AppendFormat("&{0}={1}", ImStr.ItemCrmID, Request.QueryString[ImStr.ItemCrmID]);
                    hasParent       =   true;
                }
                if (Request.QueryString[ImStr.PageNum] != null)
                {
                    sb.AppendFormat("{0}{1}={2}", hasParent ? "&":string.Empty,ImStr.PageNum, Request.QueryString[ImStr.PageNum]);
                }
                if (sb.Length > 0 )
                    return HttpUrlBuilder.BuildUrlWithCustomAttributes(PageID,sb.ToString());
                return base.UrlReferrer;
            }
            set
            {
                base.UrlReferrer = value;
            }
        }
        
        protected AddEditImagePage() : base()
        {
        }

        protected AddEditImagePage(bool HasUpd,bool HasCancel,bool HasSaveClose,bool HasDelete) : base(HasUpd,HasCancel,HasSaveClose,HasDelete)
        {
        }

        #region Metadata
        
        public string MetadataXml
        {
            get { return (string)ViewState[ImStr.DBMetadataXml]; }
            set { ViewState[ImStr.DBMetadataXml] = value; }
        }


        protected ImageMetaData Metadata  =   new ImageMetaData();


        public int GetIntMetadata(string key)
        {
            return Metadata.GetIntMetadata(key);
        }

        public string GetMetadata(string key)
        {
            return Metadata.GetMetadata(key);
        }

        public void SetIntMetadata(string key, int data)
        {
            SetMetadata(key,data.ToString());
        }

        /// <summary>
        /// Store a value under the key in the metadata parameter
        /// </summary>
        public void SetMetadata(string key, string data)
        {
            Metadata.SetMetadata(key,data);
            MetadataXml                     =   Metadata.OuterXml;
        }

        #endregion Metadata

        /// <summary>
        /// Get all jpg, gif, bmp, png files from the bulk dir
        /// </summary>
        protected string[] GetAllServerFile(string BulkDir)
        {
            string[] files1     =   System.IO.Directory.GetFiles(BulkDir, "*.jpg");
            int sz              =   0;
            if (files1.GetUpperBound(0) != -1)
                sz              =   files1.GetUpperBound(0) + 1;
            string[] files2     =   System.IO.Directory.GetFiles(BulkDir, "*.gif");
            if (files2.GetUpperBound(0) != -1)
                sz              +=  files2.GetUpperBound(0) + 1;
            string[] files3     =   System.IO.Directory.GetFiles(BulkDir, "*.bmp");
            if (files3.GetUpperBound(0) != -1)
                sz              +=  files3.GetUpperBound(0) + 1;
            string[] files4     =   System.IO.Directory.GetFiles(BulkDir, "*.png");
            if (files4.GetUpperBound(0) != -1)
                sz              +=  files4.GetUpperBound(0) + 1;
            
            string[] files      =   new string[sz];
            int i               =   0;
            for (; i <= files1.GetUpperBound(0); i++)
                files[i]        =   files1[i];
            for (int j = 0; j <= files2.GetUpperBound(0); j++)
                files[i++]      =   files2[j];
            for (int j = 0; j <= files3.GetUpperBound(0); j++)
                files[i++]      =   files3[j];
            for (int j = 0; j <= files4.GetUpperBound(0); j++)
                files[i++]      =   files4[j];
            return files;
        }

        /// <summary>
        /// Create un unique name for new images added by bulkload
        /// </summary>
        protected string FormatName(int displayOrder, string ImageName, string sdesc)
        {
            if ( string.IsNullOrEmpty(ImageName) )
            {
                if (sdesc != string.Empty && sdesc.Length < 50)
                {
                    if ( sdesc.IndexOf("{0}") > -1 )
                            ImageName   =   sdesc;
                    else    ImageName   =   sdesc + "_{0}";
                }
                else ImageName          =   "Image_{0}";
            }
            // we have many images to format (displayorder starts at 1) and no format given, we force one
            else if ( displayOrder > 0)
            {
                if ( ImageName.IndexOf("{0}") == -1)
                    ImageName = ImageName + "_{0}";
            }
            // we accept parameters in the form {0} == displayorder, {1} == short description
            if (ImageName.IndexOf("{0}") != -1)
            {
                if (ImageName.IndexOf("{1}") != -1)
                    ImageName = string.Format(ImageName, displayOrder, sdesc);
                else
                    ImageName = string.Format(ImageName, displayOrder);
            }
            return ImageName;
        }

        /// <summary>
        /// Save the image loaded from the client browser
        /// </summary>
        public void SaveImage(Guid EntID,FileInfo fi,int thumbnailWidth,int thumbnailHeight,
            int originalWidth,int originalHeight,
            string ShortDescription,string LongDescription,string Caption,int Category,string Keywords,
            bool chkIncludeExif,string selFlip,string selRotate,
            PicResizeOption thumbnailResize, PicResizeOption originalResize,Guid ImgGuid,bool update)
        {
            
            if ( CrmImageTrace.Sw.TraceVerbose )
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]AddEditImagePage EntID:{0}, thumbnailWidth:{1}, thumbnailHeight:{2}, originalWidth:{3}, originalHeight:{4},\n"+
                                    "ShortDescription:{5}, LongDescription:{6}, Caption:{7}, Keywords:{8}, chkIncludeExif:{9}, selFlip:{10}, selRotate:{11}, thumbnailResize:{12}, originalResize:{13}, ImgGuid: {14}, update:{15}, mversion:{16}",
                    new object[]{EntID,thumbnailWidth,thumbnailHeight,originalWidth,originalHeight,
                                    ShortDescription,LongDescription,Caption,Keywords,
                                    chkIncludeExif,selFlip,selRotate,thumbnailResize,originalResize,ImgGuid,update,ImageMetaData.mVersion}),CrmImageTrace.Sw.Info);
            MetadataXml         =   string.Empty;
            string ImFormat     =   portalSettings.CustomSettings[ImStr.ImageFormat].Value;
            ImageFormat fmt     =   ( ImFormat == "Jpeg" ) ? ImageFormat.Jpeg:ImageFormat.Png;
            string imExt        =   ( ImFormat == "Jpeg" ) ? "jpg":"png";

            Bitmap fullCRMImage =   null;
            // take default file prefix 1) from query 2) from module 3) from page
            string entName      =   (string.IsNullOrEmpty(RequestEntityTypename)) ? moduleSettingsDic[StStr.ModuleSettingsCRMEntityNameSettings].Value:RequestEntityTypename;
            if (string.IsNullOrEmpty(entName))
                entName = EntityName;
            if (string.IsNullOrEmpty(entName))
                entName         =   ImStr.adnimage;
            if ( string.IsNullOrEmpty(entName) )
            {
                string msg  =   string.Format("[E]AddEditImagePage SaveImage No EntityName: {0}.", EntID);
                if ( CrmImageTrace.Sw.TraceError )
                    Trace2.WriteLine( msg,CrmImageTrace.Sw.Info);
                throw new Exception(msg);
            }
            // We keep same Guid for 2 images
            if ( ImgGuid == Guid.Empty )
                ImgGuid        =   Guid.NewGuid();
            ModifiedFilename    =   string.Format("{0}_{1}.{2}",entName,ImgGuid,imExt);
            SetMetadata(ImStr.ModifiedFilename, ModifiedFilename);
            // Thumbnail have  double '-' separator
            ThumbnailFilename   =   string.Format("{0}__{1}.{2}",entName,ImgGuid,imExt);
            SetMetadata(ImStr.ThumbnailFilename, ThumbnailFilename);

            if ( CrmImageTrace.Sw.TraceVerbose)
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]AddEditImagePage loaded file: {0}, ModifiedFilename: {1}, ThumbnailFilename: {2}", fi.FullName,ModifiedFilename,ThumbnailFilename),CrmImageTrace.Sw.Info);

            //Full path of the original CRMImage
            string physicalPath =   PathToSave + ModifiedFilename;


            SetMetadata("OriginalFilename", fi.FullName);
            // We extract all the bits and convert the image to jpg format
            try
            {
                //Create a bitmap from the saved CRMImage
                fullCRMImage    =   new Bitmap(fi.FullName);
            }
            catch (Exception ex)
            {
                if ( CrmImageTrace.Sw.TraceError )
                    Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[E]AddEditImagePage new Bitmap(fi.FullName : {0}, ex :{1}", fi.FullName, ex),CrmImageTrace.Sw.Info);
                throw;
            }

            SetIntMetadata("OriginalWidth", fullCRMImage.Width);
            SetIntMetadata("OriginalHeight", fullCRMImage.Height);

            if ( chkIncludeExif )
                SetExifInformation(fullCRMImage);

            RotateFlip(fullCRMImage, selFlip, selRotate);
            Byte[] byteAr1;
            Byte[] byteAr2;
            Image2 thumbnail        =   null;
            string PathThumbnail    =   PathToSave + ThumbnailFilename;
            try
            {
                //Resize the original CRMImage with the given settings to create the thumbnail
                thumbnail           =   ResizeImage2(fullCRMImage, thumbnailWidth, thumbnailHeight, thumbnailResize);
                thumbnail.Save(PathThumbnail, fmt);
                SetIntMetadata(ImStr.MetaThumbnailWidth, thumbnail.Width);
                SetIntMetadata(ImStr.MetaThumbnailHeight, thumbnail.Height);
            }
            catch (Exception ex)
            {
                if ( CrmImageTrace.Sw.TraceError )
                    Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[E]AddEditImagePage SaveImage thumbnail.Save PathThumbnail: {0}, ex:{1}", PathThumbnail, ex),CrmImageTrace.Sw.Info);
                fullCRMImage.Dispose();
                throw;
            }
            finally
            {
                if ( thumbnail != null )
                    thumbnail.Dispose();
            }
            
            FileStream fs = null;
            try
            {
                fi                  =   new FileInfo(PathThumbnail);
                byteAr2             =   new Byte[fi.Length];
                if ( CrmImageTrace.Sw.TraceVerbose )
                    Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]AddEditImagePage SaveImage fi.Length: {0}", fi.Length),CrmImageTrace.Sw.Info);
                fs                  =   new FileStream(PathThumbnail, FileMode.Open, FileAccess.Read, FileShare.Read);
                fs.Read(byteAr2, 0, (int)fi.Length);
            }
            catch (Exception ex)
            {
                if ( CrmImageTrace.Sw.TraceError )
                    Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[E]AddEditImagePage SaveImage new FileStream PathThumbnail : {0}, ex :{1}", PathThumbnail, ex),CrmImageTrace.Sw.Info);
                fullCRMImage.Dispose();
                throw;
            }
            finally
            {
                if ( fs != null )
                    fs.Close();
            }
            
            Image2 modified = null;
            try
            {
                //Resize original image
                modified            =   ResizeImage2(fullCRMImage, originalWidth, originalHeight, originalResize);
            }
            catch (Exception ex)
            {
                if ( CrmImageTrace.Sw.TraceError )
                    Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[E]AddEditImagePage SaveImage ResizeImage : {0}, ex :{1}", PathThumbnail, ex),CrmImageTrace.Sw.Info);
                throw;
            }
            finally
            {
                fullCRMImage.Dispose();
            }

            SetIntMetadata("ModifiedWidth", modified.Width);
            SetIntMetadata("ModifiedHeight", modified.Height);


            //Save the resized one
            try
            {
                modified.Save(physicalPath, fmt);
            }
            catch (Exception ex)
            {
                if ( CrmImageTrace.Sw.TraceError )
                    Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[E]AddEditImagePage SaveImage modified.Save physicalPath : {0}, ex :{1}", physicalPath, ex),CrmImageTrace.Sw.Info);
                throw;
            }
            finally
            {
                modified.Dispose();
            }
        
            fi             =    new FileInfo(physicalPath);
            SetIntMetadata("ModifiedFileSize", (int)fi.Length);
            if ( CrmImageTrace.Sw.TraceVerbose )
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]AddEditImagePage SaveImage fi.Length: {0}", fi.Length),CrmImageTrace.Sw.Info);
            byteAr1        =    new Byte[fi.Length];
            try
            {
                fs         =    new FileStream(physicalPath, FileMode.Open, FileAccess.Read, FileShare.Read);
                fs.Read(byteAr1, 0, (int)fi.Length);
            }
            catch (Exception ex)
            {
                if ( CrmImageTrace.Sw.TraceError )
                    Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[E][E]AddEditImagePage SaveImage new FileStream physicalPath : {0}, ex :{1}", physicalPath, ex),CrmImageTrace.Sw.Info);
                throw;
            }
            finally
            {
                if (fs != null )
                    fs.Close();
            }


            SetMetadata(ImStr.DBShortDescription, ShortDescription);
            SetMetadata(ImStr.DBLongDescription, LongDescription);
            SetMetadata(ImStr.DBCaption, Caption);
            SetMetadata("UploadDate", DateTime.UtcNow.ToString());
            SetMetadata("CreatedBy", PortalSettings.CurrentIdentity.Name);

            //Add new CRMImage to the database
            try
            {
                int imageLibId  =   moduleSettingsDic[ImStr.ImageLibId].ToInt();
                if ( CrmImageTrace.Sw.TraceVerbose )
                    Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]AddEditImagePage SaveImage  EntityID: {0}, update:{1}", EntID,update),CrmImageTrace.Sw.Info);		
                if ( !update )
                    ImageDBID = ImageDB.AddCRMImage(EntID,imageLibId,Caption,Category,
                        MetadataXml, ShortDescription,Keywords, PortalSettings.CurrentIdentity.Name, DateTime.UtcNow, byteAr1, byteAr2);
                else
                    ImageDB.UpdateCRMImage(ImageDBID,imageLibId,EntID,Caption,Category,PortalSettings.CurrentIdentity.Name,
                        MetadataXml, ShortDescription, Keywords, byteAr1, byteAr2);
            }
            catch (Exception ex)
            {
                if ( CrmImageTrace.Sw.TraceError )
                    Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[E]AddEditImagePage SaveImage  EntityID: {0}, ex:{1}", EntID,ex),CrmImageTrace.Sw.Info);
                throw;
            }
        }


        protected string ConvertByteArrayToString(byte[] array)
        {
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < array.Length - 1; i++) 
                sb.Append((char)array[i]);
            return sb.ToString();
        }

        protected byte ConvertByteArrayToByte(byte[] array)
        {
            return array[0];
        }

        protected short ConvertByteArrayToShort(byte[] array)
        {
            short val = 0;
            for (int i = 0; i < array.Length; i++) val += (short)(array[i] * System.Math.Pow(2, (i * 8)));
            return val;
        }

        protected long ConvertByteArrayToLong(byte[] array)
        {
            long val = 0;
            for (int i = 0; i < array.Length; i++) val += (array[i] * (long)System.Math.Pow(2, (i * 8)));
            return val;
        }

        protected string ConvertByteArrayToRational(byte[] array)
        {
            int val1 = 0;
            int val2 = 0;

            for (int i = 0; i < 4; i++) val1 += (array[i] * (int)System.Math.Pow(2, (i * 8)));
            for (int i = 4; i < 8; i++) val2 += (array[i] * (int)System.Math.Pow(2, ((i - 4) * 8)));
            if (val2 == 1)
            {
                return val1.ToString();
            }
            else
            {
                return ((double)val1 / (double)val2).ToString();
            }
        }

        protected string ConvertByteArrayToSRational(byte[] array)
        {
            int val1 = 0;
            int val2 = 0;

            for (int i = 0; i < 4; i++) val1 += (array[i] * (int)System.Math.Pow(2, (i * 8)));
            for (int i = 4; i < 8; i++) val2 += (array[i] * (int)System.Math.Pow(2, ((i - 4) * 8)));
            if (val2 == 1)
            {
                return val1.ToString();
            }
            else
            {
                return ((double)val1 / (double)val2).ToString();
            }
        }

        protected Image2 RotateFlip(Image2 original, string flip, string rotate)
        {
            RotateFlipType rotateFlipType = RotateFlipType.RotateNoneFlipNone;

            if (flip == "None" && rotate == "180")
            {
                rotateFlipType = RotateFlipType.Rotate180FlipNone;
            }
            else if (flip == "X" && rotate == "180")
            {
                rotateFlipType = RotateFlipType.Rotate180FlipX;
            }
            else if (flip == "XY" && rotate == "180")
            {
                rotateFlipType = RotateFlipType.Rotate180FlipXY;
            }
            else if (flip == "Y" && rotate == "180")
            {
                rotateFlipType = RotateFlipType.Rotate180FlipY;
            }
            else if (flip == "None" && rotate == "270")
            {
                rotateFlipType = RotateFlipType.Rotate270FlipNone;
            }
            else if (flip == "X" && rotate == "270")
            {
                rotateFlipType = RotateFlipType.Rotate270FlipX;
            }
            else if (flip == "XY" && rotate == "270")
            {
                rotateFlipType = RotateFlipType.Rotate270FlipXY;
            }
            else if (flip == "Y" && rotate == "270")
            {
                rotateFlipType = RotateFlipType.Rotate270FlipY;
            }
            else if (flip == "None" && rotate == "90")
            {
                rotateFlipType = RotateFlipType.Rotate90FlipNone;
            }
            else if (flip == "X" && rotate == "90")
            {
                rotateFlipType = RotateFlipType.Rotate90FlipX;
            }
            else if (flip == "XY" && rotate == "90")
            {
                rotateFlipType = RotateFlipType.Rotate90FlipXY;
            }
            else if (flip == "Y" && rotate == "90")
            {
                rotateFlipType = RotateFlipType.Rotate90FlipY;
            }
            else if (flip == "None" && rotate == "None")
            {
                rotateFlipType = RotateFlipType.RotateNoneFlipNone;
            }
            else if (flip == "X" && rotate == "None")
            {
                rotateFlipType = RotateFlipType.RotateNoneFlipX;
            }
            else if (flip == "XY" && rotate == "None")
            {
                rotateFlipType = RotateFlipType.RotateNoneFlipXY;
            }
            else if (flip == "Y" && rotate == "None")
            {
                rotateFlipType = RotateFlipType.RotateNoneFlipY;
            }
            original.RotateFlip(rotateFlipType);
            return original;
        }

        protected Image2 ResizeImage2(Image2 original, int newWidth, int newHeight, PicResizeOption option)
        {
            if (original.Width == 0 || original.Height == 0 || newWidth == 0 || newHeight == 0) return null;
            if (original.Width < newWidth) newWidth = original.Width;
            if (original.Height < newHeight) newHeight = original.Height;

            switch (option)
            {
                case PicResizeOption.NoResize:
                    newWidth = original.Width;
                    newHeight = original.Height;
                    break;
                case PicResizeOption.FixedWidthHeight:
                    break;
                case PicResizeOption.MaintainAspectWidth:
                    newHeight = (newWidth * original.Height / original.Width);
                    break;
                case PicResizeOption.MaintainAspectHeight:
                    newWidth = (newHeight * original.Width / original.Height);
                    break;
            }
            Image2.GetThumbnailImageAbort dummyCallBack = new Image2.GetThumbnailImageAbort(ThumbnailCallback);
            Image2 thumbNailImg  =   original.GetThumbnailImage(newWidth,newHeight,dummyCallBack, IntPtr.Zero);
            return thumbNailImg;
            /*
           //Save the thumbnail in PNG format. 
           //You may change it to a diff format with the ImageFormat property
            thumbNailImg.Save ( Request.PhysicalApplicationPath + "pics\\" +   MyString , ImageFormat.Png);
            thumbNailImg.Dispose();
            */
        }

        //this function is reqd for thumbnail creation
        public bool ThumbnailCallback()
        {
            return false;
        }

        /// <summary>
        /// Resize a given image
        /// </summary>
        /// <param name="original">Original Bitmap that needs resizing</param>
        /// <param name="newWidth">New width of the bitmap</param>
        /// <param name="newHeight">New height of the bitmap</param>
        /// <param name="option">Option for resizing</param>
        /// <returns></returns>
        protected Bitmap ResizeImage(Bitmap original, int newWidth, int newHeight, PicResizeOption option)
        {
            if (original.Width == 0 || original.Height == 0 || newWidth == 0 || newHeight == 0) return null;
            if (original.Width < newWidth) newWidth = original.Width;
            if (original.Height < newHeight) newHeight = original.Height;

            switch (option)
            {
                case PicResizeOption.NoResize:
                    newWidth = original.Width;
                    newHeight = original.Height;
                    break;
                case PicResizeOption.FixedWidthHeight:
                    break;
                case PicResizeOption.MaintainAspectWidth:
                    newHeight = (newWidth * original.Height / original.Width);
                    break;
                case PicResizeOption.MaintainAspectHeight:
                    newWidth = (newHeight * original.Width / original.Height);
                    break;
            }
            Bitmap newBitmap = new Bitmap(newWidth, newHeight);
            Graphics g = Graphics.FromImage(newBitmap);
            g.DrawImage(original, 0, 0, newWidth, newHeight);
            return newBitmap;
        }

        protected void SetExifInformation(Bitmap bitmap)
        {
            foreach (PropertyItem pi in bitmap.PropertyItems)
            {
                switch (pi.Id)
                {
                    case 0x010F:
                        SetMetadata("EquipMake", ConvertByteArrayToString(pi.Value));
                        break;
                    case 0x0110:
                        SetMetadata("EquipModel", ConvertByteArrayToString(pi.Value));
                        break;
                    case 0x0112:
                        switch (ConvertByteArrayToShort(pi.Value))
                        {
                            case 1:
                                SetMetadata("Orientation", "upper left");
                                break;
                            case 2:
                                SetMetadata("Orientation", "upper right");
                                break;
                            case 3:
                                SetMetadata("Orientation", "lower right");
                                break;
                            case 4:
                                SetMetadata("Orientation", "lower left");
                                break;
                            case 5:
                                SetMetadata("Orientation", "upper left flipped");
                                break;
                            case 6:
                                SetMetadata("Orientation", "upper right flipped");
                                break;
                            case 7:
                                SetMetadata("Orientation", "lower right flipped");
                                break;
                            case 8:
                                SetMetadata("Orientation", "lower left flipped");
                                break;
                        }
                        break;
                    case 0x011a:
                        SetMetadata("XResolution", ConvertByteArrayToRational(pi.Value));
                        break;
                    case 0x011b:
                        SetMetadata("YResolution", ConvertByteArrayToRational(pi.Value));
                        break;
                    case 0x0128:
                        SetMetadata("ResolutionUnit", ConvertByteArrayToShort(pi.Value).ToString());
                        break;
                    case 0x0132:
                        SetMetadata("Datetime", ConvertByteArrayToString(pi.Value));
                        break;
                    case 0x0213:
                        SetMetadata("YCbCrPositioning", ConvertByteArrayToShort(pi.Value).ToString());
                        break;
                    case 0x00FE:
                        SetMetadata("NewSubfileType", ConvertByteArrayToLong(pi.Value).ToString());
                        break;
                    case 0x00FF:
                        SetMetadata("SubfileType", ConvertByteArrayToShort(pi.Value).ToString());
                        break;
                    case 0x0100:
                        SetMetadata("ImageWidth", ConvertByteArrayToLong(pi.Value).ToString());
                        break;
                    case 0x0101:
                        SetMetadata("ImageHeight", ConvertByteArrayToLong(pi.Value).ToString());
                        break;
                    case 0x0102:
                        SetMetadata("BitsPerSample", ConvertByteArrayToShort(pi.Value).ToString());
                        break;
                    case 0x0103:
                        SetMetadata("Compression", ConvertByteArrayToShort(pi.Value).ToString());
                        break;
                    case 0x0106:
                        SetMetadata("PhotometricInterp", ConvertByteArrayToShort(pi.Value).ToString());
                        break;
                    case 0x0107:
                        SetMetadata("ThreshHolding", ConvertByteArrayToShort(pi.Value).ToString());
                        break;
                    case 0x0108:
                        SetMetadata("CellWidth", ConvertByteArrayToShort(pi.Value).ToString());
                        break;
                    case 0x0109:
                        SetMetadata("CellHeight", ConvertByteArrayToShort(pi.Value).ToString());
                        break;
                    case 0x010A:
                        SetMetadata("FillOrder", ConvertByteArrayToShort(pi.Value).ToString());
                        break;
                    case 0x010D:
                        SetMetadata("DocumentName", ConvertByteArrayToString(pi.Value));
                        break;
                    case 0x010E:
                        SetMetadata("ImageDescription", ConvertByteArrayToString(pi.Value));
                        break;
                    case 0x0111:
                        SetMetadata("StripOffsets", ConvertByteArrayToLong(pi.Value).ToString());
                        break;
                    case 0x0115:
                        SetMetadata("SamplesPerPixel", ConvertByteArrayToShort(pi.Value).ToString());
                        break;
                    case 0x0116:
                        SetMetadata("RowsPerStrip", ConvertByteArrayToLong(pi.Value).ToString());
                        break;
                    case 0x0117:
                        SetMetadata("StripBytesCount", ConvertByteArrayToLong(pi.Value).ToString());
                        break;
                    case 0x0118:
                        SetMetadata("MinSampleValue", ConvertByteArrayToShort(pi.Value).ToString());
                        break;
                    case 0x0119:
                        SetMetadata("MaxSampleValue", ConvertByteArrayToShort(pi.Value).ToString());
                        break;
                    case 0x011C:
                        SetMetadata("PlanarConfig", ConvertByteArrayToShort(pi.Value).ToString());
                        break;
                    case 0x011D:
                        SetMetadata("PageName", ConvertByteArrayToString(pi.Value));
                        break;
                    case 0x011E:
                        SetMetadata("XPosition", ConvertByteArrayToRational(pi.Value));
                        break;
                    case 0x011F:
                        SetMetadata("YPosition", ConvertByteArrayToRational(pi.Value));
                        break;
                    case 0x0120:
                        SetMetadata("FreeOffset", ConvertByteArrayToLong(pi.Value).ToString());
                        break;
                    case 0x0121:
                        SetMetadata("FreeByteCounts", ConvertByteArrayToLong(pi.Value).ToString());
                        break;
                    case 0x0122:
                        SetMetadata("GrayResponseUnit", ConvertByteArrayToShort(pi.Value).ToString());
                        break;
                    case 0x0123:
                        SetMetadata("GrayResponseCurve", ConvertByteArrayToShort(pi.Value).ToString());
                        break;
                    case 0x0124:
                        SetMetadata("T4Option", ConvertByteArrayToLong(pi.Value).ToString());
                        break;
                    case 0x0125:
                        SetMetadata("T6Option", ConvertByteArrayToLong(pi.Value).ToString());
                        break;
                    case 0x0129:
                        SetMetadata("PageNumber", ConvertByteArrayToShort(pi.Value).ToString());
                        break;
                    case 0x012D:
                        SetMetadata("TransferFunction", ConvertByteArrayToShort(pi.Value).ToString());
                        break;
                    case 0x0131:
                        SetMetadata("SoftwareUsed", ConvertByteArrayToString(pi.Value));
                        break;
                    case 0x013B:
                        SetMetadata("Artist", ConvertByteArrayToString(pi.Value));
                        break;
                    case 0x013C:
                        SetMetadata("HostComputer", ConvertByteArrayToString(pi.Value));
                        break;
                    case 0x013D:
                        SetMetadata("Predictor", ConvertByteArrayToShort(pi.Value).ToString());
                        break;
                    case 0x013E:
                        SetMetadata("WhitePoint", ConvertByteArrayToRational(pi.Value));
                        break;
                    case 0x013F:
                        SetMetadata("PrimaryChromaticities", ConvertByteArrayToRational(pi.Value));
                        break;
                    case 0x0140:
                        SetMetadata("ColorMap", ConvertByteArrayToShort(pi.Value).ToString());
                        break;
                    case 0x0141:
                        SetMetadata("HalftoneHints", ConvertByteArrayToShort(pi.Value).ToString());
                        break;
                    case 0x0142:
                        SetMetadata("TileWidth", ConvertByteArrayToLong(pi.Value).ToString());
                        break;
                    case 0x0143:
                        SetMetadata("TileLength", ConvertByteArrayToLong(pi.Value).ToString());
                        break;
                    case 0x0144:
                        SetMetadata("TileOffset", ConvertByteArrayToLong(pi.Value).ToString());
                        break;
                    case 0x0145:
                        SetMetadata("TileByteCounts", ConvertByteArrayToLong(pi.Value).ToString());
                        break;
                    case 0x014C:
                        SetMetadata("InkSet", ConvertByteArrayToShort(pi.Value).ToString());
                        break;
                    case 0x014D:
                        SetMetadata("InkNames", ConvertByteArrayToString(pi.Value));
                        break;
                    case 0x014E:
                        SetMetadata("NumberOfInks", ConvertByteArrayToShort(pi.Value).ToString());
                        break;
                    case 0x0150:
                        SetMetadata("DotRange", ConvertByteArrayToShort(pi.Value).ToString());
                        break;
                    case 0x0151:
                        SetMetadata("TargetPrinter", ConvertByteArrayToString(pi.Value));
                        break;
                    case 0x0152:
                        SetMetadata("ExtraSamples", ConvertByteArrayToShort(pi.Value).ToString());
                        break;
                    case 0x0153:
                        SetMetadata("SampleFormat", ConvertByteArrayToShort(pi.Value).ToString());
                        break;
                    case 0x0156:
                        SetMetadata("TransferRange", ConvertByteArrayToShort(pi.Value).ToString());
                        break;
                    case 0x0200:
                        SetMetadata("JPEGProc", ConvertByteArrayToShort(pi.Value).ToString());
                        break;
                    case 0x0201:
                        SetMetadata("JPEGInterFormat", ConvertByteArrayToLong(pi.Value).ToString());
                        break;
                    case 0x0202:
                        SetMetadata("JPEGInterLength", ConvertByteArrayToLong(pi.Value).ToString());
                        break;
                    case 0x0203:
                        SetMetadata("JPEGRestartInterval", ConvertByteArrayToShort(pi.Value).ToString());
                        break;
                    case 0x0205:
                        SetMetadata("JPEGLosslessPredictors", ConvertByteArrayToShort(pi.Value).ToString());
                        break;
                    case 0x0206:
                        SetMetadata("JPEGPointTransforms", ConvertByteArrayToShort(pi.Value).ToString());
                        break;
                    case 0x0207:
                        SetMetadata("JPEGQTables", ConvertByteArrayToLong(pi.Value).ToString());
                        break;
                    case 0x0208:
                        SetMetadata("JPEGDCTables", ConvertByteArrayToLong(pi.Value).ToString());
                        break;
                    case 0x0209:
                        SetMetadata("JPEGACTables", ConvertByteArrayToLong(pi.Value).ToString());
                        break;
                    case 0x0211:
                        SetMetadata("YCbCrCoefficients", ConvertByteArrayToRational(pi.Value));
                        break;
                    case 0x0212:
                        SetMetadata("YCbCrSubsampling", ConvertByteArrayToShort(pi.Value).ToString());
                        break;
                    case 0x0214:
                        SetMetadata("REFBlackWhite", ConvertByteArrayToRational(pi.Value));
                        break;
                    case 0x0301:
                        SetMetadata("Gamma", ConvertByteArrayToRational(pi.Value));
                        break;
                    case 0x0302:
                        SetMetadata("ICCProfileDescriptor", ConvertByteArrayToString(pi.Value));
                        break;
                    case 0x0303:
                        switch (ConvertByteArrayToShort(pi.Value))
                        {
                            case 0:
                                SetMetadata("SRGBRenderingIntent", "perceptual");
                                break;
                            case 1:
                                SetMetadata("SRGBRenderingIntent", "relative colorimetric");
                                break;
                            case 2:
                                SetMetadata("SRGBRenderingIntent", "saturation");
                                break;
                            case 3:
                                SetMetadata("SRGBRenderingIntent", "absolute colorimetric");
                                break;
                        }
                        break;
                    case 0x0320:
                        SetMetadata("ImageTitle", ConvertByteArrayToString(pi.Value));
                        break;
                    case 0x5001:
                        SetMetadata("ResolutionXUnit", ConvertByteArrayToShort(pi.Value).ToString());
                        break;
                    case 0x5002:
                        SetMetadata("ResolutionYUnit", ConvertByteArrayToShort(pi.Value).ToString());
                        break;
                    case 0x5003:
                        SetMetadata("ResolutionXLengthUnit", ConvertByteArrayToShort(pi.Value).ToString());
                        break;
                    case 0x5004:
                        SetMetadata("ResolutionYLengthUnit", ConvertByteArrayToShort(pi.Value).ToString());
                        break;
                    case 0x5005:
                        SetMetadata("PrintFlags", ConvertByteArrayToString(pi.Value));
                        break;
                    case 0x5006:
                        SetMetadata("PrintFlagsVersion", ConvertByteArrayToShort(pi.Value).ToString());
                        break;
                    case 0x5007:
                        SetMetadata("PrintFlagsCrop", ConvertByteArrayToByte(pi.Value).ToString());
                        break;
                    case 0x5008:
                        SetMetadata("PrintFlagsBleedWidth", ConvertByteArrayToLong(pi.Value).ToString());
                        break;
                    case 0x5009:
                        SetMetadata("PrintFlagsBleedWidthScale", ConvertByteArrayToShort(pi.Value).ToString());
                        break;
                    case 0x500A:
                        SetMetadata("HalftoneLPI", ConvertByteArrayToRational(pi.Value));
                        break;
                    case 0x500B:
                        SetMetadata("HalftoneLPIUnit", ConvertByteArrayToShort(pi.Value).ToString());
                        break;
                    case 0x500C:
                        SetMetadata("HalftoneDegree", ConvertByteArrayToRational(pi.Value));
                        break;
                    case 0x500D:
                        SetMetadata("HalftoneShape", ConvertByteArrayToShort(pi.Value).ToString());
                        break;
                    case 0x500E:
                        SetMetadata("HalftoneMisc", ConvertByteArrayToLong(pi.Value).ToString());
                        break;
                    case 0x500F:
                        SetMetadata("HalftoneScreen", ConvertByteArrayToByte(pi.Value).ToString());
                        break;
                    case 0x5010:
                        SetMetadata("JPEGQuality", ConvertByteArrayToShort(pi.Value).ToString());
                        break;
                    case 0x5012:
                        SetMetadata("ThumbnailFormat", ConvertByteArrayToLong(pi.Value).ToString());
                        break;
                    case 0x5013:
                        SetMetadata(ImStr.MetaThumbnailWidth, ConvertByteArrayToLong(pi.Value).ToString());
                        break;
                    case 0x5014:
                        SetMetadata(ImStr.MetaThumbnailHeight, ConvertByteArrayToLong(pi.Value).ToString());
                        break;
                    case 0x5015:
                        SetMetadata("ThumbnailColorDepth", ConvertByteArrayToShort(pi.Value).ToString());
                        break;
                    case 0x5016:
                        SetMetadata("ThumbnailPlanes", ConvertByteArrayToShort(pi.Value).ToString());
                        break;
                    case 0x5017:
                        SetMetadata("ThumbnailRawBytes", ConvertByteArrayToLong(pi.Value).ToString());
                        break;
                    case 0x5018:
                        SetMetadata("ThumbnailSize", ConvertByteArrayToLong(pi.Value).ToString());
                        break;
                    case 0x5019:
                        SetMetadata("ThumbnailCompressedSize", ConvertByteArrayToLong(pi.Value).ToString());
                        break;
                    case 0x501B:
                        SetMetadata("ThumbnailData", ConvertByteArrayToByte(pi.Value).ToString());
                        break;
                    case 0x5020:
                        SetMetadata("ThumbnailImageWidth", ConvertByteArrayToLong(pi.Value).ToString());
                        break;
                    case 0x5021:
                        SetMetadata("ThumbnailImageHeight", ConvertByteArrayToLong(pi.Value).ToString());
                        break;
                    case 0x5022:
                        SetMetadata("ThumbnailBitsPerSample", ConvertByteArrayToShort(pi.Value).ToString());
                        break;
                    case 0x5023:
                        SetMetadata("ThumbnailCompression", ConvertByteArrayToShort(pi.Value).ToString());
                        break;
                    case 0x5024:
                        SetMetadata("ThumbnailPhotometricInterp", ConvertByteArrayToShort(pi.Value).ToString());
                        break;
                    case 0x5025:
                        SetMetadata("ThumbnailImageDescription", ConvertByteArrayToString(pi.Value));
                        break;
                    case 0x5026:
                        SetMetadata("ThumbnailEquipMake", ConvertByteArrayToString(pi.Value));
                        break;
                    case 0x5027:
                        SetMetadata("ThumbnailEquipModel", ConvertByteArrayToString(pi.Value));
                        break;
                    case 0x5028:
                        SetMetadata("ThumbnailStripOffsets", ConvertByteArrayToLong(pi.Value).ToString());
                        break;
                    case 0x5029:
                        SetMetadata("ThumbnailOrientation", ConvertByteArrayToShort(pi.Value).ToString());
                        break;
                    case 0x502A:
                        SetMetadata("ThumbnailSamplesPerPixel", ConvertByteArrayToShort(pi.Value).ToString());
                        break;
                    case 0x502B:
                        SetMetadata("ThumbnailRowsPerStrip", ConvertByteArrayToLong(pi.Value).ToString());
                        break;
                    case 0x502C:
                        SetMetadata("ThumbnailStripBytesCount", ConvertByteArrayToLong(pi.Value).ToString());
                        break;
                    case 0x502F:
                        SetMetadata("ThumbnailPlanarConfig", ConvertByteArrayToShort(pi.Value).ToString());
                        break;
                    case 0x5030:
                        SetMetadata("ThumbnailResolutionUnit", ConvertByteArrayToShort(pi.Value).ToString());
                        break;
                    case 0x5031:
                        SetMetadata("ThumbnailTransferFunction", ConvertByteArrayToShort(pi.Value).ToString());
                        break;
                    case 0x5032:
                        SetMetadata("ThumbnailSoftwareUsed", ConvertByteArrayToString(pi.Value));
                        break;
                    case 0x5033:
                        SetMetadata("ThumbnailDateTime", ConvertByteArrayToString(pi.Value));
                        break;
                    case 0x5034:
                        SetMetadata("ThumbnailArtist", ConvertByteArrayToString(pi.Value));
                        break;
                    case 0x5035:
                        SetMetadata("ThumbnailWhitePoint", ConvertByteArrayToRational(pi.Value));
                        break;
                    case 0x5036:
                        SetMetadata("ThumbnailPrimaryChromaticities", ConvertByteArrayToRational(pi.Value));
                        break;
                    case 0x5037:
                        SetMetadata("ThumbnailYCbCrCoefficients", ConvertByteArrayToRational(pi.Value));
                        break;
                    case 0x5038:
                        SetMetadata("ThumbnailYCbCrSubsampling", ConvertByteArrayToShort(pi.Value).ToString());
                        break;
                    case 0x5039:
                        SetMetadata("ThumbnailYCbCrPositioning", ConvertByteArrayToShort(pi.Value).ToString());
                        break;
                    case 0x503A:
                        SetMetadata("ThumbnailRefBlackWhite", ConvertByteArrayToRational(pi.Value));
                        break;
                    case 0x503B:
                        SetMetadata("ThumbnailCopyRight", ConvertByteArrayToString(pi.Value));
                        break;
                    case 0x5090:
                        SetMetadata("LuminanceTable", ConvertByteArrayToShort(pi.Value).ToString());
                        break;
                    case 0x5091:
                        SetMetadata("ChrominanceTable", ConvertByteArrayToShort(pi.Value).ToString());
                        break;
                    case 0x5100:
                        SetMetadata("FrameDelay", ConvertByteArrayToLong(pi.Value).ToString());
                        break;
                    case 0x5101:
                        SetMetadata("LoopCount", ConvertByteArrayToShort(pi.Value).ToString());
                        break;
                    case 0x5110:
                        SetMetadata("PixelUnit", ConvertByteArrayToByte(pi.Value).ToString());
                        break;
                    case 0x5111:
                        SetMetadata("PixelPerUnitX", ConvertByteArrayToLong(pi.Value).ToString());
                        break;
                    case 0x5112:
                        SetMetadata("PixelPerUnitY", ConvertByteArrayToLong(pi.Value).ToString());
                        break;
                    case 0x5113:
                        SetMetadata("PaletteHistogram", ConvertByteArrayToByte(pi.Value).ToString());
                        break;
                    case 0x8298:
                        SetMetadata("Copyright", ConvertByteArrayToString(pi.Value));
                        break;
                    case 0x829A:
                        SetMetadata("ExifExposureTime", ConvertByteArrayToRational(pi.Value));
                        break;
                    case 0x829D:
                        SetMetadata("ExifFNumber", ConvertByteArrayToRational(pi.Value));
                        break;
                    case 0x8769:
                        SetMetadata("ExifIFD", ConvertByteArrayToLong(pi.Value).ToString());
                        break;
                    case 0x8773:
                        SetMetadata("ICCProfile", ConvertByteArrayToByte(pi.Value).ToString());
                        break;
                    case 0x8822:
                        switch (ConvertByteArrayToShort(pi.Value))
                        {
                            case 0:
                                SetMetadata("ExifExposureProg", "Not defined");
                                break;
                            case 1:
                                SetMetadata("ExifExposureProg", "Manual");
                                break;
                            case 2:
                                SetMetadata("ExifExposureProg", "Normal Program");
                                break;
                            case 3:
                                SetMetadata("ExifExposureProg", "Aperture Priority");
                                break;
                            case 4:
                                SetMetadata("ExifExposureProg", "Shutter Priority");
                                break;
                            case 5:
                                SetMetadata("ExifExposureProg", "Creative program (biased toward depth of field)");
                                break;
                            case 6:
                                SetMetadata("ExifExposureProg", "Action program (biased toward fast shutter speed)");
                                break;
                            case 7:
                                SetMetadata("ExifExposureProg", "Portrait mode (for close-up photos with the background out of focus)");
                                break;
                            case 8:
                                SetMetadata("ExifExposureProg", "Landscape mode (for landscape photos with the background in focus)");
                                break;
                            default:
                                SetMetadata("ExifExposureProg", "Unknown");
                                break;
                        }
                        break;
                    case 0x8824:
                        SetMetadata("ExifSpectralSense", ConvertByteArrayToString(pi.Value));
                        break;
                    case 0x8825:
                        SetMetadata("GpsIFD", ConvertByteArrayToLong(pi.Value).ToString());
                        break;
                    case 0x8827:
                        SetMetadata("ExifISOSpeed", ConvertByteArrayToShort(pi.Value).ToString());
                        break;
                    case 0x9003:
                        SetMetadata("ExifDTOrig", ConvertByteArrayToString(pi.Value));
                        break;
                    case 0x9004:
                        SetMetadata("ExifDTDigitized", ConvertByteArrayToString(pi.Value));
                        break;
                    case 0x9102:
                        SetMetadata("ExifCompBPP", ConvertByteArrayToRational(pi.Value));
                        break;
                    case 0x9201:
                        SetMetadata("ExifShutterSpeed", ConvertByteArrayToSRational(pi.Value));
                        break;
                    case 0x9202:
                        SetMetadata("ExifAperture", ConvertByteArrayToRational(pi.Value));
                        break;
                    case 0x9203:
                        SetMetadata("ExifBrightness", ConvertByteArrayToSRational(pi.Value));
                        break;
                    case 0x9204:
                        SetMetadata("ExifExposureBias", ConvertByteArrayToSRational(pi.Value));
                        break;
                    case 0x9205:
                        SetMetadata("ExifMaxAperture", ConvertByteArrayToRational(pi.Value));
                        break;
                    case 0x9206:
                        SetMetadata("ExifSubjectDist", ConvertByteArrayToRational(pi.Value));
                        break;
                    case 0x9207:
                        switch (ConvertByteArrayToShort(pi.Value))
                        {
                            case 0:
                                SetMetadata("ExifMeteringMode", "Unknown");
                                break;
                            case 1:
                                SetMetadata("ExifMeteringMode", "Average");
                                break;
                            case 2:
                                SetMetadata("ExifMeteringMode", "CenterWeightedAverage");
                                break;
                            case 3:
                                SetMetadata("ExifMeteringMode", "Spot");
                                break;
                            case 4:
                                SetMetadata("ExifMeteringMode", "MultiSpot");
                                break;
                            case 5:
                                SetMetadata("ExifMeteringMode", "Pattern");
                                break;
                            case 6:
                                SetMetadata("ExifMeteringMode", "Partial");
                                break;
                            case 255:
                                SetMetadata("ExifMeteringMode", "Other");
                                break;
                            default:
                                SetMetadata("ExifMeteringMode", "Unknown");
                                break;
                        }
                        break;
                    case 0x9208:
                        switch (ConvertByteArrayToShort(pi.Value))
                        {
                            case 0:
                                SetMetadata("ExifLightSource", "Unknown");
                                break;
                            case 1:
                                SetMetadata("ExifLightSource", "Daylight");
                                break;
                            case 2:
                                SetMetadata("ExifLightSource", "Flourescent");
                                break;
                            case 3:
                                SetMetadata("ExifLightSource", "Tungsten");
                                break;
                            case 17:
                                SetMetadata("ExifLightSource", "Standard Light A");
                                break;
                            case 18:
                                SetMetadata("ExifLightSource", "Standard Light B");
                                break;
                            case 19:
                                SetMetadata("ExifLightSource", "Standard Light C");
                                break;
                            case 20:
                                SetMetadata("ExifLightSource", "D55");
                                break;
                            case 21:
                                SetMetadata("ExifLightSource", "D65");
                                break;
                            case 22:
                                SetMetadata("ExifLightSource", "D75");
                                break;
                            case 255:
                                SetMetadata("ExifLightSource", "Other");
                                break;
                            default:
                                SetMetadata("ExifLightSource", "Unknown");
                                break;
                        }
                        break;
                    case 0x9209:
                        switch (ConvertByteArrayToShort(pi.Value))
                        {
                            case 0:
                                SetMetadata("ExifFlash", "Flash did not fire");
                                break;
                            case 1:
                                SetMetadata("ExifFlash", "Flash fired");
                                break;
                            case 5:
                                SetMetadata("ExifFlash", "Strobe return light not detected");
                                break;
                            default:
                                SetMetadata("ExifFlash", "Uknown");
                                break;
                        }
                        break;
                    case 0x920A:
                        SetMetadata("ExifFocalLength", ConvertByteArrayToRational(pi.Value));
                        break;
                    case 0x9290:
                        SetMetadata("ExifDTSubsec", ConvertByteArrayToString(pi.Value));
                        break;
                    case 0x9291:
                        SetMetadata("ExifDTOrigSS", ConvertByteArrayToString(pi.Value));
                        break;
                    case 0x9292:
                        SetMetadata("ExifDTDigSS", ConvertByteArrayToString(pi.Value));
                        break;
                    case 0xA001:
                        switch (ConvertByteArrayToLong(pi.Value))
                        {
                            case 0x1:
                                SetMetadata("ExifColorSpace", "sRGB");
                                break;
                            case 0xFFFF:
                                SetMetadata("ExifColorSpace", "Uncalibrated");
                                break;
                            default:
                                SetMetadata("ExifColorSpace", "Reserved");
                                break;
                        }
                        break;
                    case 0xA002:
                        SetMetadata("ExifPixXDim", ConvertByteArrayToLong(pi.Value).ToString());
                        break;
                    case 0xA003:
                        SetMetadata("ExifPixYDim", ConvertByteArrayToLong(pi.Value).ToString());
                        break;
                    case 0xA004:
                        SetMetadata("ExifRelatedWav", ConvertByteArrayToString(pi.Value));
                        break;
                    case 0xA005:
                        SetMetadata("ExifInterop", ConvertByteArrayToLong(pi.Value).ToString());
                        break;
                    case 0xA20B:
                        SetMetadata("ExifFlashEnergy", ConvertByteArrayToRational(pi.Value));
                        break;
                    case 0xA20E:
                        SetMetadata("ExifFocalXRes", ConvertByteArrayToRational(pi.Value));
                        break;
                    case 0xA20F:
                        SetMetadata("ExifFocalYRes", ConvertByteArrayToRational(pi.Value));
                        break;
                    case 0xA210:
                        switch (ConvertByteArrayToShort(pi.Value))
                        {
                            case 2:
                                SetMetadata("ExifFocalResUnit", "Inch");
                                break;
                            case 3:
                                SetMetadata("ExifFocalResUnit", "Centimeter");
                                break;
                        }
                        break;
                    case 0xA214:
                        SetMetadata("ExifSubjectLoc", ConvertByteArrayToShort(pi.Value).ToString());
                        break;
                    case 0xA215:
                        SetMetadata("ExifExposureIndex", ConvertByteArrayToRational(pi.Value));
                        break;
                    case 0xA217:
                        switch (ConvertByteArrayToShort(pi.Value))
                        {
                            case 1:
                                SetMetadata("ExifSensingMethod", "Not defined");
                                break;
                            case 2:
                                SetMetadata("ExifSensingMethod", "One-chip color area sensor");
                                break;
                            case 3:
                                SetMetadata("ExifSensingMethod", "Two-chip color area sensor");
                                break;
                            case 4:
                                SetMetadata("ExifSensingMethod", "Three-chip color area sensor");
                                break;
                            case 5:
                                SetMetadata("ExifSensingMethod", "Color sequential area sensor");
                                break;
                            case 7:
                                SetMetadata("ExifSensingMethod", "Trilinear sensor");
                                break;
                            case 8:
                                SetMetadata("ExifSensingMethod", "Color sequential linear sensor");
                                break;
                            default:
                                SetMetadata("ExifSensingMethod", "Reserved");
                                break;
                        }
                        break;
                }
            }
        }
   
    }
}